package cn.com.wxd.dao.website;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.wxd.dao.HibernateDao;
import cn.com.wxd.entity.website.ArticleInfo;
import cn.com.wxd.common.CharUtil;
import cn.com.wxd.common.PageInfo;
import cn.com.wxd.util.dao.QueryParamHeper;
import cn.com.wxd.common.data.KVMap;

/**
 * Title:ArticleDaoImpl.java
 * Description:cn.com.wxd.dao.article
 * <p>
 * Company: wxd网站系统
 * Copyright: Copyright (c) 2015
 * All right reserved.
 * Created time: 2015-11-24 下午6:15:11
 *
 * @author WangXuDong
 * @version 1.0
 */
public class ArticleDaoImpl extends HibernateDao implements ArticleDao {
    private static final Logger log = LoggerFactory.getLogger(ArticleDaoImpl.class);

    @Override
    public ArticleInfo selectArticleById(long id) {
        Session session = currentSession();
        ArticleInfo acticleInfo = session.get(ArticleInfo.class, id);
        //ArticleInfo acticleInfo = (ArticleInfo) session.createCriteria(ArticleInfo.class)
        //        .add(Restrictions.idEq(id)).uniqueResult();
        return acticleInfo;
    }

    @Override
    public List<ArticleInfo> selectArticlesByCaid(int caid, PageInfo page) {
        Session session = currentSession();
        if (page == null) {
            page = new PageInfo();
        }
        Criteria c1 = session.createCriteria(ArticleInfo.class);
        long count = CharUtil.stringParsLong(c1.add(Restrictions.eq("caId", caid))
                .setProjection(Projections.rowCount())
                .uniqueResult()
                .toString());
        page.setTotalCount(count);
        if (page.getPageCount() < page.getPageIndex()) {
            page.setPageIndex(1);
        }
        Criteria c2 = session.createCriteria(ArticleInfo.class);
        List<ArticleInfo> lists;
        c2.add(Restrictions.eq("caId", caid));
        c2.setFirstResult(page.getPageSize() * (page.getPageIndex() - 1));
        c2.setMaxResults(page.getPageSize());
        c2.addOrder(Order.desc("orderId"));
        lists = c2.list();
        return lists;
    }

    @Override
    public boolean insertArticle(ArticleInfo articleInfo) {
        Session session = currentSession();
        try {
            session.saveOrUpdate(articleInfo);
            return true;
        } catch (Exception e) {
            log.error("保存到数据库失败：" + e.getMessage(), e);
        }
        return false;
    }

    @Override
    public boolean deleteArticle(long id) {
        Session session = currentSession();
        try {
            session.delete(session.load(ArticleInfo.class, id));
            return true;
        } catch (Exception e) {
            log.error("文章删除失败");
        }
        return false;
    }

    @Override
    public List<ArticleInfo> selectArticles(PageInfo page) {
        Session session = currentSession();
        if (page == null) {
            page = new PageInfo();
        }
        Criteria ccount = session.createCriteria(ArticleInfo.class);
        page.setTotalCount(CharUtil.stringParsLong(ccount.setProjection(Projections.rowCount())
                .uniqueResult()
                .toString()));

        Criteria c = session.createCriteria(ArticleInfo.class);
        c.addOrder(Order.desc("orderId"));
        c.setFirstResult(page.getPageSize() * (page.getPageIndex() - 1));
        c.setMaxResults(page.getPageSize());
        return (List<ArticleInfo>)c.list();
    }

    @Override
    public List<ArticleInfo> selectArticle(KVMap<String, Object> param, KVMap<String, String> order,
                                          List<String> fuzzField, PageInfo page) {
        Session session = currentSession();
        DetachedCriteria dc = DetachedCriteria.forClass(ArticleInfo.class);
        DetachedCriteria dc2 = DetachedCriteria.forClass(ArticleInfo.class);

        try {
            if (param == null) {
                param = new KVMap<>();
            }
            for (int i = 0; i < param.size(); i++) {
                if (fuzzField != null) {
                    boolean res = false;
                    for (int j = 0; j < fuzzField.size(); j++) {
                        if (param.getKeyIndex(i).equals(fuzzField.get(j))) {
                            res = true;
                            break;
                        }
                    }
                    if (res) {
                        dc.add(Restrictions
                                .ilike(param.getKeyIndex(i), (String) param.getValueIndex(i), MatchMode.ANYWHERE));
                        dc2.add(Restrictions
                                .ilike(param.getKeyIndex(i), (String) param.getValueIndex(i), MatchMode.ANYWHERE));
                    } else {
                        dc.add(Restrictions.eq(param.getKeyIndex(i), param.getValueIndex(i)));
                        dc2.add(Restrictions.eq(param.getKeyIndex(i), param.getValueIndex(i)));
                    }
                } else {
                    dc.add(Restrictions.eq(param.getKeyIndex(i), param.getValueIndex(i)));
                    dc2.add(Restrictions.eq(param.getKeyIndex(i), param.getValueIndex(i)));
                }

            }
            Criteria ccount = dc2.getExecutableCriteria(session);
            if(page == null){
                page = new PageInfo(1 , 24);
            }
            page.setTotalCount(CharUtil.stringParsLong(ccount.setProjection(Projections.rowCount())
                    .uniqueResult()
                    .toString()));
            Criteria c = dc.getExecutableCriteria(session);
            c = c.setFirstResult(page.getPageSize() * (page.getPageIndex() - 1)).setMaxResults(page.getPageSize());
            if (order == null) {
                order = new KVMap<>();
            }
            for (int i = 0; i < order.size(); i++) {
                if (order.getValueIndex(i).equalsIgnoreCase("DESC")) {
                    c.addOrder(Order.desc(order.getKeyIndex(i)));
                } else {
                    c.addOrder(Order.asc(order.getKeyIndex(i)));
                }
            }
            return (List<ArticleInfo>) c.list();
        } catch (Exception e) {
            log.error("查询出错，方法selectAtrcle(List<KeyValue<String, Object>> param, KVMap<S......"
                    + e.getMessage(), e);
        }
        return null;
    }

    @Override
    public boolean deleteArticles(long[] ids) {
        Session session = currentSession();
        try {

            String HQL = "DELETE FROM ArticleInfo a WHERE 1=2";
            for (int i = 0; i < ids.length; i++) {
                if (i == 0) {
                    HQL += "OR id IN(" + ids[i] + "";
                } else {
                    HQL = HQL + "," + ids[i];
                }
            }
            if (ids.length > 0) {
                HQL += ")";
            }
            session.createQuery(HQL).executeUpdate();
            return true;
        } catch (Exception e) {
            log.error("批量删除文章发生错误:" + e.getMessage(), e);
        }
        return false;
    }

    @Override
    public List<ArticleInfo> selectArticleByIndexId(String[] indexIds) {
        Session session = currentSession();
        List<ArticleInfo> list = null;
        try {

            String HQL = "FROM ArticleInfo a WHERE 1=2";
            if (indexIds == null || indexIds.length == 0) {
                return null;
            }
            for (int i = 0; i < indexIds.length; i++) {
                if (indexIds[i] != null && !indexIds[i].trim().equalsIgnoreCase("null") && !indexIds[i].trim()
                        .equals("")) {
                    if (i == 0) {
                        HQL += " OR indexId IN('" + indexIds[i] + "'";
                    } else {
                        HQL = HQL + ",'" + indexIds[i] + "'";
                    }

                }
            }
            HQL += ")";
            Query query = session.createQuery(HQL);
            list = (List<ArticleInfo>) query.list();

        } catch (Exception e) {
            log.error("根据文章索引获取文章失败");
        }
        return list;
    }

    @Override
    public List<ArticleInfo> selectArticleByids(String[] ids) {
        Session session = currentSession();
        List<ArticleInfo> list = null;
        try {

            String HQL = "FROM ArticleInfo a WHERE 1=2";
            for (int i = 0; i < ids.length; i++) {
                if (i == 0) {
                    HQL += "OR id IN('" + ids[i] + "'";
                } else {
                    HQL = HQL + ",'" + ids[i] + "'";
                }
            }
            if (ids.length > 0) {
                HQL += ")";
            }
            HQL += " order by a.orderId desc";
            Query query = session.createQuery(HQL);
            list = (List<ArticleInfo>) query.list();

        } catch (Exception e) {
            log.error("根据文章ID获取文章失败", e);
        }
        return list;
    }

    @Override
    public long selectMaxOrderId() {
        Session session = currentSession();
        Criteria c = session.createCriteria(ArticleInfo.class);
        c.setProjection(Projections.max("orderId"));
        Long in = (Long) c.uniqueResult();
        if (in == null) {
            return 0;
        }
        return in+1;
    }

    @Override
    public boolean updateClickQuan(HashMap<String, String> param) {

        Session session = currentSession();
        Criteria c = session.createCriteria(ArticleInfo.class);
        List<ArticleInfo> list = null;
        try {
            if (param != null) {
                for (String key : param.keySet()) {
                    c.add(Restrictions.eq(key, CharUtil.stringParsInt(param.get(key))));
                }
                list = (List<ArticleInfo>) (c.addOrder(Order.desc("orderId")).list());
            }
            for (int i = 0; i < list.size(); i++) {
                list.get(i).setArticleClick((list.get(i).getArticleClick() + 1));  //点击量加1
                session.update(list.get(i));
            }
        } catch (Exception e) {
            log.error("访问量添加失败:" + e.getMessage());
            return false;
        }
        return true;
    }

    @Override
    public boolean updateOrder(long newOrdId, long oldOrdId) {
        Session session = currentSession();
        try {
            Criteria c = session.createCriteria(ArticleInfo.class);
            Criteria c2 = session.createCriteria(ArticleInfo.class);
            ArticleInfo oldai = (ArticleInfo) (c.add(Restrictions.eq("orderId", oldOrdId)).uniqueResult());
            ArticleInfo newai = (ArticleInfo) (c2.add(Restrictions.eq("orderId", newOrdId)).uniqueResult());
            oldai.setOrderId(newOrdId);
            newai.setOrderId(oldOrdId);

            session.update(oldai);    //交换orderId
            session.update(newai);
        } catch (Exception e) {
            log.error("排序异常：" + e.getMessage());
            return false;
        }
        return true;
    }

    @Override
    public List<ArticleInfo> selectArticlesByCaid(int caid, int maxCount) {
        Session session = currentSession();
        Criteria c2 = session.createCriteria(ArticleInfo.class);
        List<ArticleInfo> lists = c2.add(Restrictions.eq("caId", caid))
                .setFirstResult(0)
                .setMaxResults(maxCount)
                .addOrder(Order.desc("orderId"))
                .list();
        return lists;
    }

    @Override
    public List<ArticleInfo> selectArticlesByCaid(int caid, int maxCount, boolean isTimeOrder) {
        Session session = currentSession();
        Criteria c2 = session.createCriteria(ArticleInfo.class);
        List<ArticleInfo> lists = c2.add(Restrictions.eq("caId", caid))
                .setFirstResult(0)
                .setMaxResults(maxCount)
                .addOrder(Order.desc("dateTime"))
                .list();
        return lists;
    }

    @Override
    public int selectArticleCount() {
        Session session = currentSession();
        Criteria c2 = session.createCriteria(ArticleInfo.class);
        int num = CharUtil.stringParsInt(c2.setProjection(Projections.rowCount()).uniqueResult().toString());
        return num;
    }

    @Override
    public boolean updateArticleCaid(long[] ids, int caid) {
        Session session = currentSession();
        int row = 0;
        try {
            String HQL = "update ArticleInfo a set a.caId='" + caid + "' WHERE 1=2";
            for (int i = 0; i < ids.length; i++) {
                HQL += " or a.id='" + ids[i] + "'";
            }
            Query query = session.createQuery(HQL);
            row = query.executeUpdate();
        } catch (Exception e) {
            log.error("文章更新失败" + e.getMessage());
        }
        if (row > 0) {
            return true;
        }
        return false;
    }

    @Override
    public long selectCountByCaid(int caid) {
        Session session = currentSession();
        Criteria c2 = session.createCriteria(ArticleInfo.class);
        c2.add(Restrictions.eq("caId", caid));
        int num = CharUtil.stringParsInt(c2.setProjection(Projections.rowCount()).uniqueResult().toString());
        return num;
    }

    @Override
    public boolean insertArticles(List<ArticleInfo> articlelist) {
        Session session = currentSession();
        try {
            for (ArticleInfo articleInfo : articlelist) {
                session.evict(articleInfo);  // 将对象从session中脱离
                articleInfo.setId(0);
                session.save(articleInfo);
            }
            return true;
        } catch (Exception e) {
            log.error("文章更新失败" + e.getMessage());
        }
        return false;
    }

    @Override
    public KVMap<String, List<ArticleInfo>> selectArticleBatch(List<QueryParamHeper> listqph) {

        Session session = currentSession();
        KVMap<String, List<ArticleInfo>> map = new KVMap<String, List<ArticleInfo>>();
        try {
            for (int i = 0; i < listqph.size(); i++) {
                Criteria c = session.createCriteria(ArticleInfo.class);
                KVMap<String, Object> kv = listqph.get(i).getParam();
                for (int j = 0; j < kv.size(); j++) {
                    if (listqph.get(i).getIsFuzzy()) {
                        c.add(Restrictions.ilike(kv.getKeyIndex(j), (String) kv.getValueIndex(j), MatchMode.ANYWHERE));
                    } else {
                        c.add(Restrictions.eq(kv.getKeyIndex(j), kv.getValueIndex(j)));
                    }
                }
                KVMap<String, String> kv2 = listqph.get(i).getOrder();
                for (int j = 0; j < kv2.size(); j++) {
                    if (kv2.getValueIndex(j).equals(QueryParamHeper.DESC)) {
                        c.addOrder(Order.desc(kv2.getKeyIndex(j)));
                    }
                    if (kv2.getValueIndex(j).equals(QueryParamHeper.ASC)) {
                        c.addOrder(Order.asc(kv2.getKeyIndex(j)));
                    }
                }
                c.setMaxResults(listqph.get(i).getMaxSize());

                List<ArticleInfo> alist = c.list();
                map.put(listqph.get(i).getQueryName(), alist);
            }
        } catch (Exception e) {
            log.error("数据库查询失败:" + e.getMessage());
        }
        return map;
    }

    @Override
    public ArticleInfo selectNextArt(long orderId, int caid) {
        Session session = currentSession();
        try {
            Criteria c = session.createCriteria(ArticleInfo.class);
            c.add(Restrictions.eq("caId", caid))
                    .add(Restrictions.eq("state", "P").ignoreCase())
                    .add(Restrictions.lt("orderId", orderId))
                    .addOrder(Order.desc("orderId"))
                    .setFirstResult(0)
                    .setMaxResults(1);
            ArticleInfo ai = (ArticleInfo) c.uniqueResult();
            return ai;
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }

    @Override
    public ArticleInfo selectPrevArt(long orderId, int caid) {
        Session session = currentSession();
        try {
            Criteria c = session.createCriteria(ArticleInfo.class);
            c.add(Restrictions.eq("caId", caid))
                    .add(Restrictions.eq("state", "P").ignoreCase())
                    .add(Restrictions.gt("orderId", orderId))
                    .addOrder(Order.asc("orderId"))
                    .setFirstResult(0)
                    .setMaxResults(1);
            ArticleInfo ai = (ArticleInfo) c.uniqueResult();
            return ai;
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }

    @Override
    public ArticleInfo selectArticleByOrderId(long OrderId) {
        Session session = currentSession();
        Criteria c2 = session.createCriteria(ArticleInfo.class);
        ArticleInfo ai = (ArticleInfo) c2.add(Restrictions.eq("orderId", OrderId))
                .uniqueResult();
        return ai;
    }

    @Override
    public boolean updateArticle(long id, HashMap<String, Object> param) {
        Session session = currentSession();
        if (param != null && param.size() > 0) {
            String paramkey = "";
            List<Object> paramvalue = new ArrayList<Object>();
            for (String key : param.keySet()) {
                if (param.get(key) != null && !param.get(key).equals("null")) {
                    paramkey += "a." + key + "=?,";
                    paramvalue.add(param.get(key));
                }
            }
            paramkey = paramkey.substring(0, paramkey.length() - 1);
            String HQL = "UPDATE ArticleInfo a SET " + paramkey + " where a.id = " + id;
            Query query = session.createQuery(HQL);
            for (int i = 0; i < paramvalue.size(); i++) {
                query.setParameter(i, paramvalue.get(i));
            }
            int reint = query.executeUpdate();
            if (reint == 1) {
                return true;
            }
        }
        return false;
    }
}
